package com.mycompany.myapp.web.rest;

import com.mycompany.myapp.JhipsterApp;
import com.mycompany.myapp.domain.SUser;
import com.mycompany.myapp.repository.SUserRepository;
import com.mycompany.myapp.service.SUserService;
import com.mycompany.myapp.service.dto.SUserDTO;
import com.mycompany.myapp.service.mapper.SUserMapper;
import com.mycompany.myapp.web.rest.errors.ExceptionTranslator;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.Validator;

import javax.persistence.EntityManager;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.ZoneOffset;
import java.time.ZoneId;
import java.util.List;

import static com.mycompany.myapp.web.rest.TestUtil.sameInstant;
import static com.mycompany.myapp.web.rest.TestUtil.createFormattingConversionService;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

/**
 * Integration tests for the {@Link SUserResource} REST controller.
 */
@SpringBootTest(classes = JhipsterApp.class)
public class SUserResourceIT {

    private static final String DEFAULT_USERNAME = "AAAAAAAAAA";
    private static final String UPDATED_USERNAME = "BBBBBBBBBB";

    private static final String DEFAULT_PASSWORD = "AAAAAAAAAA";
    private static final String UPDATED_PASSWORD = "BBBBBBBBBB";

    private static final String DEFAULT_AVATAR = "AAAAAAAAAA";
    private static final String UPDATED_AVATAR = "BBBBBBBBBB";

    private static final String DEFAULT_EMAIL = "AAAAAAAAAA";
    private static final String UPDATED_EMAIL = "BBBBBBBBBB";

    private static final String DEFAULT_PHONE = "AAAAAAAAAA";
    private static final String UPDATED_PHONE = "BBBBBBBBBB";

    private static final Boolean DEFAULT_IS_ACTIVE = false;
    private static final Boolean UPDATED_IS_ACTIVE = true;

    private static final ZonedDateTime DEFAULT_CREATE_TIME = ZonedDateTime.ofInstant(Instant.ofEpochMilli(0L), ZoneOffset.UTC);
    private static final ZonedDateTime UPDATED_CREATE_TIME = ZonedDateTime.now(ZoneId.systemDefault()).withNano(0);

    private static final ZonedDateTime DEFAULT_UPDATE_TIME = ZonedDateTime.ofInstant(Instant.ofEpochMilli(0L), ZoneOffset.UTC);
    private static final ZonedDateTime UPDATED_UPDATE_TIME = ZonedDateTime.now(ZoneId.systemDefault()).withNano(0);

    @Autowired
    private SUserRepository sUserRepository;

    @Autowired
    private SUserMapper sUserMapper;

    @Autowired
    private SUserService sUserService;

    @Autowired
    private MappingJackson2HttpMessageConverter jacksonMessageConverter;

    @Autowired
    private PageableHandlerMethodArgumentResolver pageableArgumentResolver;

    @Autowired
    private ExceptionTranslator exceptionTranslator;

    @Autowired
    private EntityManager em;

    @Autowired
    private Validator validator;

    private MockMvc restSUserMockMvc;

    private SUser sUser;

    @BeforeEach
    public void setup() {
        MockitoAnnotations.initMocks(this);
        final SUserResource sUserResource = new SUserResource(sUserService);
        this.restSUserMockMvc = MockMvcBuilders.standaloneSetup(sUserResource)
            .setCustomArgumentResolvers(pageableArgumentResolver)
            .setControllerAdvice(exceptionTranslator)
            .setConversionService(createFormattingConversionService())
            .setMessageConverters(jacksonMessageConverter)
            .setValidator(validator).build();
    }

    /**
     * Create an entity for this test.
     *
     * This is a static method, as tests for other entities might also need it,
     * if they test an entity which requires the current entity.
     */
    public static SUser createEntity(EntityManager em) {
        SUser sUser = new SUser()
            .username(DEFAULT_USERNAME)
            .password(DEFAULT_PASSWORD)
            .avatar(DEFAULT_AVATAR)
            .email(DEFAULT_EMAIL)
            .phone(DEFAULT_PHONE)
            .isActive(DEFAULT_IS_ACTIVE)
            .createTime(DEFAULT_CREATE_TIME)
            .updateTime(DEFAULT_UPDATE_TIME);
        return sUser;
    }
    /**
     * Create an updated entity for this test.
     *
     * This is a static method, as tests for other entities might also need it,
     * if they test an entity which requires the current entity.
     */
    public static SUser createUpdatedEntity(EntityManager em) {
        SUser sUser = new SUser()
            .username(UPDATED_USERNAME)
            .password(UPDATED_PASSWORD)
            .avatar(UPDATED_AVATAR)
            .email(UPDATED_EMAIL)
            .phone(UPDATED_PHONE)
            .isActive(UPDATED_IS_ACTIVE)
            .createTime(UPDATED_CREATE_TIME)
            .updateTime(UPDATED_UPDATE_TIME);
        return sUser;
    }

    @BeforeEach
    public void initTest() {
        sUser = createEntity(em);
    }

    @Test
    @Transactional
    public void createSUser() throws Exception {
        int databaseSizeBeforeCreate = sUserRepository.findAll().size();

        // Create the SUser
        SUserDTO sUserDTO = sUserMapper.toDto(sUser);
        restSUserMockMvc.perform(post("/api/s-users")
            .contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(sUserDTO)))
            .andExpect(status().isCreated());

        // Validate the SUser in the database
        List<SUser> sUserList = sUserRepository.findAll();
        assertThat(sUserList).hasSize(databaseSizeBeforeCreate + 1);
        SUser testSUser = sUserList.get(sUserList.size() - 1);
        assertThat(testSUser.getUsername()).isEqualTo(DEFAULT_USERNAME);
        assertThat(testSUser.getPassword()).isEqualTo(DEFAULT_PASSWORD);
        assertThat(testSUser.getAvatar()).isEqualTo(DEFAULT_AVATAR);
        assertThat(testSUser.getEmail()).isEqualTo(DEFAULT_EMAIL);
        assertThat(testSUser.getPhone()).isEqualTo(DEFAULT_PHONE);
        assertThat(testSUser.getIsActive()).isEqualTo(DEFAULT_IS_ACTIVE);
        assertThat(testSUser.getCreateTime()).isEqualTo(DEFAULT_CREATE_TIME);
        assertThat(testSUser.getUpdateTime()).isEqualTo(DEFAULT_UPDATE_TIME);
    }

    @Test
    @Transactional
    public void createSUserWithExistingId() throws Exception {
        int databaseSizeBeforeCreate = sUserRepository.findAll().size();

        // Create the SUser with an existing ID
        sUser.setId(1L);
        SUserDTO sUserDTO = sUserMapper.toDto(sUser);

        // An entity with an existing ID cannot be created, so this API call must fail
        restSUserMockMvc.perform(post("/api/s-users")
            .contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(sUserDTO)))
            .andExpect(status().isBadRequest());

        // Validate the SUser in the database
        List<SUser> sUserList = sUserRepository.findAll();
        assertThat(sUserList).hasSize(databaseSizeBeforeCreate);
    }


    @Test
    @Transactional
    public void getAllSUsers() throws Exception {
        // Initialize the database
        sUserRepository.saveAndFlush(sUser);

        // Get all the sUserList
        restSUserMockMvc.perform(get("/api/s-users?sort=id,desc"))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(jsonPath("$.[*].id").value(hasItem(sUser.getId().intValue())))
            .andExpect(jsonPath("$.[*].username").value(hasItem(DEFAULT_USERNAME.toString())))
            .andExpect(jsonPath("$.[*].password").value(hasItem(DEFAULT_PASSWORD.toString())))
            .andExpect(jsonPath("$.[*].avatar").value(hasItem(DEFAULT_AVATAR.toString())))
            .andExpect(jsonPath("$.[*].email").value(hasItem(DEFAULT_EMAIL.toString())))
            .andExpect(jsonPath("$.[*].phone").value(hasItem(DEFAULT_PHONE.toString())))
            .andExpect(jsonPath("$.[*].isActive").value(hasItem(DEFAULT_IS_ACTIVE.booleanValue())))
            .andExpect(jsonPath("$.[*].createTime").value(hasItem(sameInstant(DEFAULT_CREATE_TIME))))
            .andExpect(jsonPath("$.[*].updateTime").value(hasItem(sameInstant(DEFAULT_UPDATE_TIME))));
    }
    
    @Test
    @Transactional
    public void getSUser() throws Exception {
        // Initialize the database
        sUserRepository.saveAndFlush(sUser);

        // Get the sUser
        restSUserMockMvc.perform(get("/api/s-users/{id}", sUser.getId()))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(jsonPath("$.id").value(sUser.getId().intValue()))
            .andExpect(jsonPath("$.username").value(DEFAULT_USERNAME.toString()))
            .andExpect(jsonPath("$.password").value(DEFAULT_PASSWORD.toString()))
            .andExpect(jsonPath("$.avatar").value(DEFAULT_AVATAR.toString()))
            .andExpect(jsonPath("$.email").value(DEFAULT_EMAIL.toString()))
            .andExpect(jsonPath("$.phone").value(DEFAULT_PHONE.toString()))
            .andExpect(jsonPath("$.isActive").value(DEFAULT_IS_ACTIVE.booleanValue()))
            .andExpect(jsonPath("$.createTime").value(sameInstant(DEFAULT_CREATE_TIME)))
            .andExpect(jsonPath("$.updateTime").value(sameInstant(DEFAULT_UPDATE_TIME)));
    }

    @Test
    @Transactional
    public void getNonExistingSUser() throws Exception {
        // Get the sUser
        restSUserMockMvc.perform(get("/api/s-users/{id}", Long.MAX_VALUE))
            .andExpect(status().isNotFound());
    }

    @Test
    @Transactional
    public void updateSUser() throws Exception {
        // Initialize the database
        sUserRepository.saveAndFlush(sUser);

        int databaseSizeBeforeUpdate = sUserRepository.findAll().size();

        // Update the sUser
        SUser updatedSUser = sUserRepository.findById(sUser.getId()).get();
        // Disconnect from session so that the updates on updatedSUser are not directly saved in db
        em.detach(updatedSUser);
        updatedSUser
            .username(UPDATED_USERNAME)
            .password(UPDATED_PASSWORD)
            .avatar(UPDATED_AVATAR)
            .email(UPDATED_EMAIL)
            .phone(UPDATED_PHONE)
            .isActive(UPDATED_IS_ACTIVE)
            .createTime(UPDATED_CREATE_TIME)
            .updateTime(UPDATED_UPDATE_TIME);
        SUserDTO sUserDTO = sUserMapper.toDto(updatedSUser);

        restSUserMockMvc.perform(put("/api/s-users")
            .contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(sUserDTO)))
            .andExpect(status().isOk());

        // Validate the SUser in the database
        List<SUser> sUserList = sUserRepository.findAll();
        assertThat(sUserList).hasSize(databaseSizeBeforeUpdate);
        SUser testSUser = sUserList.get(sUserList.size() - 1);
        assertThat(testSUser.getUsername()).isEqualTo(UPDATED_USERNAME);
        assertThat(testSUser.getPassword()).isEqualTo(UPDATED_PASSWORD);
        assertThat(testSUser.getAvatar()).isEqualTo(UPDATED_AVATAR);
        assertThat(testSUser.getEmail()).isEqualTo(UPDATED_EMAIL);
        assertThat(testSUser.getPhone()).isEqualTo(UPDATED_PHONE);
        assertThat(testSUser.getIsActive()).isEqualTo(UPDATED_IS_ACTIVE);
        assertThat(testSUser.getCreateTime()).isEqualTo(UPDATED_CREATE_TIME);
        assertThat(testSUser.getUpdateTime()).isEqualTo(UPDATED_UPDATE_TIME);
    }

    @Test
    @Transactional
    public void updateNonExistingSUser() throws Exception {
        int databaseSizeBeforeUpdate = sUserRepository.findAll().size();

        // Create the SUser
        SUserDTO sUserDTO = sUserMapper.toDto(sUser);

        // If the entity doesn't have an ID, it will throw BadRequestAlertException
        restSUserMockMvc.perform(put("/api/s-users")
            .contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(sUserDTO)))
            .andExpect(status().isBadRequest());

        // Validate the SUser in the database
        List<SUser> sUserList = sUserRepository.findAll();
        assertThat(sUserList).hasSize(databaseSizeBeforeUpdate);
    }

    @Test
    @Transactional
    public void deleteSUser() throws Exception {
        // Initialize the database
        sUserRepository.saveAndFlush(sUser);

        int databaseSizeBeforeDelete = sUserRepository.findAll().size();

        // Delete the sUser
        restSUserMockMvc.perform(delete("/api/s-users/{id}", sUser.getId())
            .accept(TestUtil.APPLICATION_JSON_UTF8))
            .andExpect(status().isNoContent());

        // Validate the database contains one less item
        List<SUser> sUserList = sUserRepository.findAll();
        assertThat(sUserList).hasSize(databaseSizeBeforeDelete - 1);
    }

    @Test
    @Transactional
    public void equalsVerifier() throws Exception {
        TestUtil.equalsVerifier(SUser.class);
        SUser sUser1 = new SUser();
        sUser1.setId(1L);
        SUser sUser2 = new SUser();
        sUser2.setId(sUser1.getId());
        assertThat(sUser1).isEqualTo(sUser2);
        sUser2.setId(2L);
        assertThat(sUser1).isNotEqualTo(sUser2);
        sUser1.setId(null);
        assertThat(sUser1).isNotEqualTo(sUser2);
    }

    @Test
    @Transactional
    public void dtoEqualsVerifier() throws Exception {
        TestUtil.equalsVerifier(SUserDTO.class);
        SUserDTO sUserDTO1 = new SUserDTO();
        sUserDTO1.setId(1L);
        SUserDTO sUserDTO2 = new SUserDTO();
        assertThat(sUserDTO1).isNotEqualTo(sUserDTO2);
        sUserDTO2.setId(sUserDTO1.getId());
        assertThat(sUserDTO1).isEqualTo(sUserDTO2);
        sUserDTO2.setId(2L);
        assertThat(sUserDTO1).isNotEqualTo(sUserDTO2);
        sUserDTO1.setId(null);
        assertThat(sUserDTO1).isNotEqualTo(sUserDTO2);
    }

    @Test
    @Transactional
    public void testEntityFromId() {
        assertThat(sUserMapper.fromId(42L).getId()).isEqualTo(42);
        assertThat(sUserMapper.fromId(null)).isNull();
    }
}
